/*
 * Copyright (c) 2023. Shanghai HEADING information Engineering Co., Ltd. All rights reserved.
 */

package com.lovely602.boot.bootdemo.controller.java;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.lovely602.boot.bootdemo.domain.common.RestResponse;
import com.lovely602.boot.bootdemo.domain.common.log.Watcher;

import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;

/**
 * @author lizhixing
 */
@Api(tags = "copyOnWriteArrayList服务")
@RestController
@RequestMapping(value = "/v1/bff/web/copyOnWriteArrayList",
    produces = "application/json;charset=utf-8")
@Slf4j
public class CopyOnWriteArrayListController {

  // 测试并发写的性能
  @GetMapping("write")
  public RestResponse<Map> testWrite() {
    List<Integer> copyOnWriteArrayList = new CopyOnWriteArrayList<>();
    List<Integer> synchronizedList = Collections.synchronizedList(new ArrayList<>());
    List<Integer> arrayList = new ArrayList<>();

    int loopCount = 100000;
    Watcher.watch("Write:copyOnWriteArrayList");
    // 循环100000次并发往CopyOnWriteArrayList写入随机元素
    IntStream.rangeClosed(1, loopCount).parallel()
        .forEach(__ -> copyOnWriteArrayList.add(ThreadLocalRandom.current().nextInt(loopCount)));
    Watcher.watch("Write:synchronizedList");
    // 循环100000次并发往加锁的ArrayList写入随机元素
    IntStream.rangeClosed(1, loopCount).parallel()
        .forEach(__ -> synchronizedList.add(ThreadLocalRandom.current().nextInt(loopCount)));
    Watcher.watch("Write:arrayList");
    // 循环100000次并发往ArrayList写入随机元素
    IntStream.rangeClosed(1, loopCount).parallel()
        .forEach(__ -> arrayList.add(ThreadLocalRandom.current().nextInt(loopCount)));
    Map result = new HashMap<>();
    result.put("copyOnWriteArrayList", copyOnWriteArrayList.size());
    result.put("synchronizedList", synchronizedList.size());
    result.put("arrayList", arrayList.size());
    return RestResponse.success(result);
  }

  // 测试并发读的性能
  @GetMapping("read")
  public RestResponse<Map> testRead() {
    // 创建两个测试对象
    List<Integer> copyOnWriteArrayList = new CopyOnWriteArrayList<>();
    List<Integer> synchronizedList = Collections.synchronizedList(new ArrayList<>());
    List<Integer> arrayList = new ArrayList<>();
    // 填充数据
    addAll(copyOnWriteArrayList);
    addAll(synchronizedList);
    addAll(arrayList);

    int loopCount = 1000000;
    Watcher.watch("Read:copyOnWriteArrayList");
    // 循环1000000次并发读从CopyOnWriteArrayList随机查询元素
    IntStream.rangeClosed(1, loopCount).parallel()
        .forEach(__ -> copyOnWriteArrayList.get(ThreadLocalRandom.current().nextInt(loopCount)));
    Watcher.watch("Read:synchronizedList");
    // 循环1000000次并发读从加锁ArrayList随机查询元素
    IntStream.rangeClosed(1, loopCount).parallel()
        .forEach(__ -> synchronizedList.get(ThreadLocalRandom.current().nextInt(loopCount)));
    Watcher.watch("Read:arrayList");
    // 循环1000000次并发读从ArrayList随机查询元素
    IntStream.rangeClosed(1, loopCount).parallel()
        .forEach(__ -> arrayList.get(ThreadLocalRandom.current().nextInt(loopCount)));
    Map result = new HashMap<>();
    result.put("copyOnWriteArrayList", copyOnWriteArrayList.size());
    result.put("synchronizedList", synchronizedList.size());
    result.put("arrayList", arrayList.size());
    return RestResponse.success(result);
  }

  // 帮助方法用来填充List
  private void addAll(List<Integer> list) {
    list.addAll(IntStream.rangeClosed(1, 1000000).boxed().collect(Collectors.toList()));
  }

}
